<template>
  <div class="person">
    <!-- 选项式写法 -->
    <!-- <h1>姓名：{{ name }}</h1>
        <h1>年龄：{{ age }}</h1> -->

    <!-- 组合式写法-->
    <!-- <h1>姓名：{{ a }}</h1>
        <h1>年龄：{{ b }}</h1>
    <h1>姓名：{{ name }}</h1>
    <h1>年龄：{{ age }}</h1>
    <h1>地址：{{ address }}</h1>
    <button @click="updateName">修改名字</button>
    <button @click="updateAge">修改年龄</button>
    <button @click="showTel">查看联系方式</button> -->

    <!-- 012.reactive创建_对象类型的响应式数据 -->
    <h2>车辆信息：一辆{{ car.brand }},价值为:{{ car.price }}万</h2>
    <button @click="updateCarprice">修改汽车的价格</button>
    <button @click="updateCarBrand">修改汽车的品牌</button>
    <button @click="updateCar">修改汽车的信息</button>
    <br />
    <h2>游戏列表:</h2>
    <ul>
      <li v-for="game in games" :key="game.id">游戏名:{{ game.name }}</li>
    </ul>
    <button @click="updateFirstGameName">修改第一个游戏的名字</button>
    <hr />
    <h2>测试{{ obj.a.b.c }}</h2>
    <button @click="updateObj">改变测试</button>
    <hr />
    <h2>总和：{{ sum }}</h2>
    <button @click="updateSum">点我一下sum+10</button>
    <hr />
    <h1>toRefs与toRef</h1>
    <h2>姓名：{{ person.name }}</h2>
    <h2>年龄：{{ person.age }}</h2>
    <h2>解构赋值姓名：{{ name }}</h2>
    <h2>解构赋值年龄：{{ age }},toRef:{{ nianling }}</h2>
    <button @click="updatePersonName">修改Person的名字</button>
    <button @click="updatePersonAge">修改Person的年龄</button>
  </div>
</template>

<!-- <script lang="ts">
  export default {
    // name: 'person'
    // 选项（配置）式 API ——》OptionsApi （Vue2 使用）
    // data(){
    //     return{
    //         name:'张三',
    //         age:18,
    //         tel:'110'
    //     }
    // },
    // methods:{
    //     // 展示电话号码
    //     showTel(){
    //         alert(this.tel);
    //     },
    //     // 修改姓名
    //     updateName(){
    //         this.name = 'zhangsan'
    //     },
    //     // 修改年龄
    //     updateAge(){
    //         this.age = this.age + 1
    //     }
    // },
    // 面试题1：OptionsApi 和 CompositionApi 能否共存？
    // 答：可以的
    // 面试题2：OptionsApi 是否可以调用 CompositionApi 里定义的数据？
    // 答：可以，因为setup()的生命周期比 beforeCreate 还早，已经将数据解析好了，但是需要加 this 才可以获取到 setup 里的数据。但是反过来不行。
    // 组合式 API ——》 CompositionApi （Vue3 使用）d
    // setup 内部不要用 this，this代表的是undefined，Vue3 中弱化了 this
    // setup() {
    // 数据定义，原来是写在 data 中，现在 name,age,tel 不是响应式
    //   let name = '张三';
    //   let age = 18;
    //   let tel = '110';
    //   let address = '厦门市';
    //   // 方法（直接写函数）
    //   function showTel() {
    //     alert(tel);
    //   }
    //   function updateName() {
    //     name = 'zhang-san'; // 注意，这样修改 name，页面是没有变化的
    //     console.log(name); // name 确实改了，但是 name 不是响应式的
    //   }
    //   function updateAge() {
    //     age += 1; // 与上述 name 同理
    //   }
    // 可以返回 key:value 的形式
    // return {a:name,b:age}
    // 也可以用简短的形式
    // return 的作用是将数据、方法(函数)交出去，模板（template）才可以使用
    //   return { name, age, address, showTel, updateName, updateAge };
    // setup 的返回值也可以是一个函数
    // return ()=> '哈哈'
    // }
  };
</script> -->

<!-- setup 语法糖（这个会自动return） -->
<!-- 组件名可以写在 scrpit标签里，但是需要下载插件：npm i vite-plugin-vue-setup-extend -D -->
<script lang="ts" setup name="Person_ZLX">
  // // 11.ref创建_基本类型的响应式数据
  // // 引入 ref （目的是构造响应式数据）
  // import { ref } from 'vue';
  // // 响应式数据构造
  // let name = ref('张三');
  // let age = ref(18);
  // let tel = '110';
  // let address = '厦门市';

  // // name 和 age 成为 RefImpl 的构造对象了
  // console.log(name);
  // console.log(age);
  // console.log(tel);
  // console.log(address);

  // // 方法（直接写函数）
  // function showTel() {
  //   alert(tel);
  // }

  // function updateName() {
  //   // name = 'zhang-san'; // 注意，这样修改 name，页面是没有变化的
  //   // 使用响应式需要加上 字段.value
  //   name.value = 'zhang-san';
  //   console.log(name); // name 确实改了，但是 name 不是响应式的
  // }

  // function updateAge() {
  //   // age += 1; // 与上述 name 同理
  //   // 使用响应式需要加上 字段.value
  //   age.value += 1;
  // }

  // 012.reactive创建_对象类型的响应式数据
  import { reactive, ref } from 'vue';
  // 数据，对象类型
  let car = reactive({ brand: '奔驰', price: 100 });
  console.log(car);
  let games = reactive([
    { id: 1, gameName: 'Honor of Kings', name: '王者荣耀' },
    { id: 2, gameName: 'One Piece', name: '海贼王' }
  ]);
  let obj = reactive({
    a: { b: { c: 666 } }
  });
  let sum = ref(0);

  // 方法
  function updateCarprice() {
    car.price += 10;
  }

  function updateCarBrand() {
    car.brand = '桑塔纳';
  }

  // 针对 reactive 重新分配一个对象，会失去响应式（可以使用 Object.assign 去整体替换）
  function updateCar() {
    // car = { brand: '库里南', price: 200 }; // 这种写法是不可以更新页面的数据的
    // car = reactive({ brand: '库里南', price: 200 }); // 这种写法是不可以更新页面的数据的
    // Object.assign(obj1,obj2,obj3)，会将obj2里的keyvalue加到obj1，会将obj3里的keyvalue加到obj1,这个写法可以更新
    Object.assign(car, { brand: '库里南', price: 200 });
  }

  // 针对 ref,必须要用到 .value
  // function updateCar() {
  //   car.value = { brand: '库里南', price: 200 };
  // }

  function updateFirstGameName() {
    games[0].name = '七龙珠';
  }

  function updateObj() {
    obj.a.b.c = 888;
  }
  function updateSum() {
    sum.value += 10;
  }

  // 015.toRefs与toRef
  // 解构赋值变成响应式的格式，需要引入 toRefs
  import { toRefs, toRef } from 'vue';
  let person = reactive({
    name: '李四',
    age: 18
  });

  // 解构赋值（直接解构的不是响应式的）
  // let { name, age } = person;
  // console.log(name, age);

  // 解构赋值响应式
  let { name, age } = toRefs(person);
  console.log(name);
  console.log(age);

  // toRef 取出 对象里的一个对象的key值
  let nianling = toRef(person, 'age');
  console.log(nianling.value);

  function updatePersonName() {
    // 使用了 toRefs 后 name 和 person.name 是同一个，只要name变化那么 person.name 也会变化
    // person.name += '~';
    name.value += '~';
  }

  function updatePersonAge() {
    // person.age += 1;
    age.value += 1;
  }

  //
</script>

<style scoped>
  /*  样式 */
  .person {
    background-color: skyblue;
    box-shadow: 0 0 10px;
    border-radius: 10px;
    padding: 20px;
  }

  button {
    margin: 0 5px;
  }
</style>
